package cn.admin.remoting.serialize.impl;

import cn.admin.remoting.Remoting;
import cn.admin.remoting.impl.ConnectionRequest;
import cn.admin.remoting.impl.ConnectionResponse;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import java.io.IOException;

public class RemotingProtocolEncoder extends ProtocolEncoderAdapter {

    private ConnRequestSerialization reqSerialize = new ConnRequestSerialization();
    private ConnResponseSerialization rspSerialize = new ConnResponseSerialization();

    @Override
    public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {

        boolean isRequest = message instanceof ConnectionRequest;
        boolean isResponse = message instanceof ConnectionResponse;

        if (!isRequest && !isResponse) {
            throw new IOException("不可识别的序列化对象: " + message);
        } else {
            SliceOutputStream os = new SliceOutputStream();
            byte protocol;
            if (isRequest) {
                ConnectionRequest connReq = (ConnectionRequest) message;
                protocol = connReq.getSerializeProtocol();
                this.reqSerialize.serialize(connReq,protocol,os);
            } else {
                ConnectionResponse connRsp = (ConnectionResponse) message;
                protocol = connRsp.getSerializeProtocol();
                this.rspSerialize.serialize(connRsp,protocol,os);
            }

            for (int i = 0;i < os.allSlice().length;i ++) {
                byte[] slice = os.allSlice()[i];
                out.write(ByteBuffer.wrap(slice));
            }

            if (Remoting.serialUtil().isReuseSerialization()) {
                synchronized (this) {
                    out.flush();
                }
            }
        }

    }
}
